<template>
    <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="120px" class="demo-ruleForm" :size="formSize"
        status-icon>
        <el-form-item label="商品类型" prop="categoryId">
            <el-select v-model="ruleForm.categoryId" class="m-2" placeholder="选择商品类型">
                <el-option v-for="item in category" :key="item.id" :label="item.name" :value="item.id"
                    @click="getAttributeKey(item.id)" />
            </el-select>
        </el-form-item>
        <el-form-item label="商品名">
            <el-input v-model="spuTable.name" />
        </el-form-item>
        <el-form-item label="商品图片">
            <el-upload class="avatar-uploader1" action="" :http-request="uploadSpuPicture" :show-file-list="false">
                <img v-if="spuTable.picture" :src="spuTable.picture" class="avatar1" />
                <el-icon v-else class="avatar-uploader-icon1">
                    <Plus />
                </el-icon>
            </el-upload>
        </el-form-item>
        <el-form-item label="商品属性">
            <el-table :data="table.attribute" style="width: 100%">
                <el-table-column prop="title" label="属性名" width="180" />
                <el-table-column label="属性值">
                    <template v-slot:default="{ row }">
                        <el-input v-if="row.type === '1'" v-model="row.value" />
                        <el-radio-group v-else-if="row.type === '2'" v-model="row.value">
                            <el-radio v-for="(item, index) in row.options" :key="index" :label="item"></el-radio>
                        </el-radio-group>
                        <el-checkbox-group v-else-if="row.type === '3'" v-model="row.values">
                            <el-checkbox v-for="(item, index) in row.options" :key="index" :label="item"></el-checkbox>
                        </el-checkbox-group>
                    </template>
                </el-table-column>
            </el-table>
        </el-form-item>
        <el-form-item label="商品规格">
            <el-table :data="tableData" style="width: 100%" max-height="250">
                <el-table-column prop="specKey" label="规格名" width="180" />
                <el-table-column label="规格值" width="400">
                    <template #default="{ row }">
                        <el-checkbox-group v-model="row.specValue">
                            <el-checkbox v-for="option in row.specOptions" :label="option" :key="option"></el-checkbox>
                        </el-checkbox-group>
                    </template>
                </el-table-column>
                <el-table-column fixed="right" label="操作">
                    <template #default="scope">
                        <el-button link type="primary" size="small"
                            @click.prevent="onAddSpecOptions(scope.row.id)">添加规格选项</el-button>
                        <el-button link type="primary" size="small"
                            @click.prevent="onDeleteSpecOptions(scope.row.id)">删除规格选项</el-button>
                        <el-button link type="primary" size="small" @click.prevent="deleteRow(scope.row.id)">
                            移除规格
                        </el-button>
                    </template>
                </el-table-column>
            </el-table>
            <el-button class="mt-4" style="width: 100%" @click="onAddItem">添加规格</el-button>
            <el-dialog v-model="dialogFormVisible" title="添加规格">
                <el-form :model="form">
                    <el-form-item label="规格名" :label-width="formLabelWidth">
                        <el-input v-model="form.title" autocomplete="off" />
                    </el-form-item>
                </el-form>
                <template #footer>
                    <span class="dialog-footer">
                        <el-button @click="dialogFormVisible = false">取消</el-button>
                        <el-button type="primary" @click="addSpecKey">
                            添加
                        </el-button>
                    </span>
                </template>
            </el-dialog>
            <el-dialog v-model="dialogFormVisible1" title="添加规格选项">
                <el-form :model="form1">
                    <el-form-item label="选项名" :label-width="formLabelWidth1">
                        <el-input v-model="form1.option" autocomplete="off" />
                    </el-form-item>
                </el-form>
                <template #footer>
                    <span class="dialog-footer">
                        <el-button @click="dialogFormVisible1 = false">取消</el-button>
                        <el-button type="primary" @click="addSpecOptions">
                            添加
                        </el-button>
                    </span>
                </template>
            </el-dialog>
            <el-dialog v-model="dialogFormVisible2" title="删除规格选项">
                <el-form :model="form2">
                    <el-form-item label="选项名" :label-width="formLabelWidth2">
                        <el-select v-model="form2.id" class="m-2" placeholder="选择商品类型">
                            <el-option v-for="item in specOptionsSlelect.specOptions" :key="item.id" :label="item.title"
                                :value="item.id" />
                        </el-select>
                    </el-form-item>
                </el-form>
                <template #footer>
                    <span class="dialog-footer">
                        <el-button @click="dialogFormVisible2 = false">取消</el-button>
                        <el-button type="primary" @click="deleteSpecOptions">
                            删除
                        </el-button>
                    </span>
                </template>
            </el-dialog>
        </el-form-item>
        <el-form-item label="商品库存">
            <el-table :data="cartesianProduct">
                <el-table-column v-for="specKey in specKeys" :key="specKey" :label="specKey">
                    <template #default="{ row }">
                        {{ row[specKey] }}
                    </template>
                </el-table-column>
                <el-table-column label="商品图片">
                    <template #default="{ row, $index }">
                        <el-upload class="avatar-uploader" action="" :http-request="uploadSkuPicture"
                            :data="{ rowIndex: $index }" :show-file-list="false" :before-upload="beforeAvatarUpload">
                            <img v-if="row.picture" :src="row.picture" class="avatar" />
                            <el-icon v-else class="avatar-uploader-icon">
                                <Plus />
                            </el-icon>
                        </el-upload>
                    </template>
                </el-table-column>
                <el-table-column label="销售价（元）">
                    <template #default="{ row }">
                        <el-input-number v-model="row.price" :precision="2" :step="0.1" :max="10000" />
                    </template>
                </el-table-column>
                <el-table-column label="市场价（元）">
                    <template #default="{ row }">
                        <el-input-number v-model="row.marketPrice" :precision="2" :step="0.1" :max="10000" />
                    </template>
                </el-table-column>
                <el-table-column label="成本价（元）">
                    <template #default="{ row }">
                        <el-input-number v-model="row.costPrice" :precision="2" :step="0.1" :max="10000" />
                    </template>
                </el-table-column>
                <el-table-column label="库存">
                    <template #default="{ row }">
                        <el-input-number v-model="row.stock" :precision="0" :step="1" :max="100000" />
                    </template>
                </el-table-column>
                <el-table-column label="状态">
                    <template #default="{ row }">
                        <el-select v-model="row.status" class="m-2" placeholder="Select">
                            <el-option v-for="item in statusOptions" :key="item.value" :label="item.label"
                                :value="item.value" />
                        </el-select>
                    </template>
                </el-table-column>
            </el-table>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="submitForm(ruleFormRef)">
                添加
            </el-button>
            <el-button @click="resetForm(ruleFormRef)">重置</el-button>
        </el-form-item>
    </el-form><br>
</template>
  
<script lang="ts" setup>
import { Ref, computed, onMounted, reactive, ref, watch, watchEffect } from 'vue'
import { ElNotification, UploadProps, type FormInstance, type FormRules, ElMessage, UploadRequestOptions } from 'element-plus'
import api from '@/api';
import { Plus } from '@element-plus/icons-vue'

interface RuleForm {
    categoryId: string
}

const formSize = ref('default')
const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive<RuleForm>({
    categoryId: '',
})

const rules = reactive<FormRules<RuleForm>>({
    categoryId: [
        {
            required: true,
            message: '请选择商品类型',
            trigger: 'blur'
        },
    ],

})

const submitForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    await formEl.validate((valid, fields) => {
        if (valid) {
            // 调用processData函数处理数据
            console.log(ruleForm.categoryId)
            console.log(table.attribute)
            console.log(cartesianProduct.value)
            console.log(spuTable.value)
            if(cartesianProduct.value.length === 1 &&  cartesianProduct.value[0].name === ''){
                ElNotification({
                        title: 'Error',
                        message: "商品规格不能为空",
                        type: 'error',
                        duration: 1500
                    })
            }else{
                api.shop.addSpuSku(
                {
                    categoryId: ruleForm.categoryId,
                    attrValueList: table.attribute,
                    skuList: cartesianProduct.value,
                    spu: spuTable.value
                }
            )
                .then(response => {
                    ElNotification({
                        title: 'Success',
                        message: response.data.msg,
                        type: 'success',
                        duration: 1500
                    })
                    resetForm(ruleFormRef.value)
                })
                .catch(error => {
                    form2.id = ''
                    ElNotification({
                        title: 'Error',
                        message: error.data.msg,
                        type: 'error',
                        duration: 1500
                    })
                })
            }
        } else {
            console.log('error submit!', fields)
        }
    })
}

const resetForm = (formEl: FormInstance | undefined) => {
    if (!formEl) return
    formEl.resetFields()
    // 清空value和values
    table.attribute.forEach(attr => {
        attr.value = '';
        attr.values = [];
    });
    tableData.value = []
    cartesianProduct.value = []
    spuTable.value.name = ''
    spuTable.value.picture = ''
}


const category = ref<any[]>([])

onMounted(() => {
    getCategoryList()
})

function getCategoryList() {
    api.shop.getCategoryList()
        .then(response => {
            category.value = response.data.data
        })
        .catch(error => {
            ElNotification({
                title: 'Error',
                message: error.data.msg,
                type: 'error',
                duration: 1500
            })
        })
}



const table = reactive({
    attribute: [
        {
            attrKeyId: '',
            title: '',
            type: '',
            options: [],
            value: '',
            values: []
        }
    ]
})

watch(table, (newTable) => {
    newTable.attribute.forEach((item) => {
        if (item.values && item.values.length > 0) {
            item.value = item.values.join(',');
        }
    })
})

function getAttributeKey(id: string) {
    api.shop.getAttributeKey({ categoryId: id })
        .then(response => {
            table.attribute = response.data.data.map((item: any) => {
                return {
                    attrKeyId: item.id,
                    title: item.title,
                    type: item.type,
                    options: item.options.split(',')
                }
            })
        })
        .catch(error => {
            ElNotification({
                title: 'Error',
                message: error.data.msg,
                type: 'error',
                duration: 1500
            })
        })
    getSpecVoByCategoryId(id)
}


const tableData = ref([
    {
        id: '',
        specKey: '',
        specOptions: [],
        specValue: []
    }
])


const deleteRow = (index: number) => {
    api.shop.deleteSpecKeyById(index)
        .then(response => {
            getSpecVoByCategoryId(ruleForm.categoryId)
            ElNotification({
                title: 'Success',
                message: response.data.msg,
                type: 'success',
                duration: 1500
            })
        })
        .catch(error => {
            form2.id = ''
            ElNotification({
                title: 'Error',
                message: error.data.msg,
                type: 'error',
                duration: 1500
            })
        })
}

const onAddItem = () => {
    dialogFormVisible.value = true
}

function getSpecVoByCategoryId(id: string) {
    api.shop.getSpecVoByCategoryId({ categoryId: id })
        .then(response => {
            tableData.value = response.data.data.map((item: any) => {
                return {
                    id: item.id,
                    specKey: item.title,
                    specOptions: item.specOptions,
                    specValue: []
                }
            })
        })
        .catch(error => {
            ElNotification({
                title: 'Error',
                message: error.data.msg,
                type: 'error',
                duration: 1500
            })
        })

}


const dialogTableVisible = ref(false)
const dialogFormVisible = ref(false)
const formLabelWidth = '140px'

const form = reactive({
    title: '',
})

function addSpecKey() {
    if (form.title === '' || ruleForm.categoryId === '') {
        ElNotification({
            title: 'Error',
            message: '规格名不能为空',
            type: 'error',
            duration: 1500
        })
        return
    } else {
        api.shop.addSpecKey({ title: form.title, categoryId: ruleForm.categoryId })
            .then(response => {
                dialogFormVisible.value = false
                getSpecVoByCategoryId(ruleForm.categoryId)
                form.title = ''
                ElNotification({
                    title: 'Success',
                    message: response.data.msg,
                    type: 'success',
                    duration: 1500
                })
            })
            .catch(error => {
                form.title = ''
                ElNotification({
                    title: 'Error',
                    message: error.data.msg,
                    type: 'error',
                    duration: 1500
                })
            })
    }
}

const dialogTableVisible1 = ref(false)
const dialogFormVisible1 = ref(false)
const formLabelWidth1 = '140px'

const form1 = reactive({
    option: '',
    specKeyId: ''
})

function onAddSpecOptions(id: string) {
    dialogFormVisible1.value = true
    form1.specKeyId = id
}

function addSpecOptions() {
    if (form1.option === '') {
        ElNotification({
            title: 'Error',
            message: '选项名不能为空',
            type: 'error',
            duration: 1500
        })
        return
    }
    api.shop.addSpecOptions({ title: form1.option, specKeyId: form1.specKeyId, categoryId: ruleForm.categoryId })
        .then(response => {
            dialogFormVisible1.value = false
            getSpecVoByCategoryId(ruleForm.categoryId)
            form1.option = ''
            form1.specKeyId = ''
            ElNotification({
                title: 'Success',
                message: response.data.msg,
                type: 'success',
                duration: 1500
            })
        })
        .catch(error => {
            form1.option = ''
            form1.specKeyId = ''
            ElNotification({
                title: 'Error',
                message: error.data.msg,
                type: 'error',
                duration: 1500
            })
        })
}

const dialogTableVisible2 = ref(false)
const dialogFormVisible2 = ref(false)
const formLabelWidth2 = '140px'

const form2 = reactive({
    id: '',
    option: '',
})

const specOptionsSlelect = reactive({
    specOptions: [
        {
            id: '',
            title: ''
        }
    ]
})

function onDeleteSpecOptions(id: string) {
    dialogFormVisible2.value = true
    getSpecOptionsByKeyId(id)
}

function getSpecOptionsByKeyId(id: string) {
    api.shop.getSpecOptionsByKeyId({ specKeyId: id })
        .then(response => {
            specOptionsSlelect.specOptions = response.data.data
        })
        .catch(error => {
            form1.option = ''
            form1.specKeyId = ''
            ElNotification({
                title: 'Error',
                message: error.data.msg,
                type: 'error',
                duration: 1500
            })
        })
}

function deleteSpecOptions() {
    api.shop.deleteSpecOptionById(form2.id)
        .then(response => {
            dialogFormVisible2.value = false
            form2.id = ''
            getSpecVoByCategoryId(ruleForm.categoryId)
            ElNotification({
                title: 'Success',
                message: response.data.msg,
                type: 'success',
                duration: 1500
            })
        })
        .catch(error => {
            form2.id = ''
            ElNotification({
                title: 'Error',
                message: error.data.msg,
                type: 'error',
                duration: 1500
            })
        })

}

const specKeys = ref([] as string[]);

const cartesianProduct: Ref<({ [key: string]: string })[]> = ref([]);

const calculateCartesianProduct = () => {
    const tempProduct: ({ [key: string]: string })[] = [{}];

    for (let i = 0; i < tableData.value.length; i++) {
        const optionValues = tableData.value[i].specValue;
        const newProduct: ({ [key: string]: string })[] = [];

        if (optionValues.length === 0) {
            for (let j = 0; j < tempProduct.length; j++) {
                const product = tempProduct[j];
                const copy = JSON.parse(JSON.stringify(product));
                copy[tableData.value[i].specKey] = '';
                newProduct.push(copy);
            }
        } else {
            for (let j = 0; j < tempProduct.length; j++) {
                const product = tempProduct[j];

                for (let k = 0; k < optionValues.length; k++) {
                    const copy = JSON.parse(JSON.stringify(product));
                    copy[tableData.value[i].specKey] = optionValues[k];
                    newProduct.push(copy);
                }
            }
        }

        tempProduct.length = 0;
        tempProduct.push(...newProduct);
    }

    cartesianProduct.value = tempProduct.map(product => {
        const newProduct: { [key: string]: string } = {
            ...product,
            price: '0', // 添加 price 属性
            stock: '0', // 添加 stock 属性
            marketPrice: '0',
            costPrice: '0',
            status: "1",
            picture: ''
        };

        // 拼接键和值
        const productString = Object.entries(newProduct)
            .filter(([key, value]) => value !== '' && key !== 'status') // 过滤空值和status属性
            .map(([key, value]) => key + ':' + value)
            .join(';');

        newProduct.properties = productString

        const nameString = Object.entries(newProduct)
            .filter(([key, value]) => value !== '' && key !== 'status' && key !== 'properties'&& key !== 'price'&& key !== 'marketPrice'&& key !== 'costPrice'&& key !== 'picture'&& key !== 'stock')
            .map(([key, value]) => value)
            .join(' ');

        newProduct.name = nameString

        return newProduct;
    });

    specKeys.value = tableData.value.map(item => item.specKey);
};

watchEffect(() => {
    calculateCartesianProduct();
});

const statusOptions = [
    {
        value: '1',
        label: '启用',
    },
    {
        value: '0',
        label: '禁用',
    },
]




const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {

    return true
}



const uploadSkuPicture: UploadProps['httpRequest'] = (uploadFile) => {
    const index = Number(uploadFile.data.rowIndex);
    const file = uploadFile.file
    // 创建FormData对象
    const formData = new FormData();
    // 将上传的文件添加到FormData中
    formData.append('file', file);
    return api.shop.uploadSkuPicture(formData)
        .then(response => {
            // 在这里可以处理提交成功后的逻辑
            // 根据索引值找到对应的行数据
            const row = cartesianProduct.value[index];

            // 更新行数据的属性
            row.picture = response.data.data; // 以picture属性为例
            ElNotification({
                title: 'Success',
                message: response.data.msg,
                type: 'success',
                duration: 1500
            });

        })
        .catch(error => {
            ElNotification({
                title: 'Error',
                message: error.data.msg,
                type: 'error',
                duration: 1500
            });
        });
}


const uploadSpuPicture: UploadProps['httpRequest'] = (uploadFile) => {
    const file = uploadFile.file
    // 创建FormData对象
    const formData = new FormData();
    // 将上传的文件添加到FormData中
    formData.append('file', file);
    return api.shop.uploadSkuPicture(formData)
        .then(response => {
            // 在这里可以处理提交成功后的逻辑
            spuTable.value.picture = response.data.data
            ElNotification({
                title: 'Success',
                message: response.data.msg,
                type: 'success',
                duration: 1500
            });

        })
        .catch(error => {
            ElNotification({
                title: 'Error',
                message: error.data.msg,
                type: 'error',
                duration: 1500
            });
        });
}

const spuTable = ref({
    name: '',
    picture: ''
})

</script>

<style scoped>
.avatar-uploader .avatar {
    width: 80px;
    height: 80px;
    display: block;
}

.avatar-uploader .el-upload {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 80px;
    height: 80px;
    text-align: center;
}




.avatar-uploader1 .avatar1 {
    width: 178px;
    height: 178px;
    display: block;
}

.avatar-uploader1 .el-upload1 {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon1 {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    text-align: center;
}
</style>